#!/usr/bin/env python
#-*- coding: utf-8 -*-

import sys, re
from Game import Player, Game, Event


class GameParser(object):
    
    def __init__(self):
        # RE_gameparts finds the major parts of a Game
        self.RE_gameparts = re.compile("""
            [^"]*                       # prelude
            "(?P<name> [^"]* )"         # the Game’s name
            \s*
            \{(?P<players> .*? )\}      # the Players
            \s*
            \{(?P<actions>(?:           # the Players’ actions
                [^\{\}]*
                \{
                [^\{\}]*
                \}
                [^\{\}]*
                )*?)\}   
            \s*
            (?P<comment> "[^"]*" )?       # an optional comment
            \s*
            \{(?P<events>(?:            # the Events
                [^\{\}]*
                \{
                [^\{\}]*
                \}
                [^\{\}]*
                )*?)\}   
            \s*
            (?P<matrix> [\d\.\s]* )       # the outcome/event matrix (a flat list)
            .*
            """, re.VERBOSE)

        # regex for a {}-list of quoted strings: { "..." "..." "..." }
        self.strlist_RE = re.compile(r'"([^"]*)"')
        # regex for a {}-list of {}-lists: { { ... } { ... } { ... } }
        self.listlist_RE = re.compile(r'\{([^\{\}]*)\}')
        # regex for an Event: { "name" payoffs }
        self.event_parts_RE = re.compile(r'\s*"(?P<name>.*)"(?P<payoffs>.*)')
        # regex for a comma-split list of payoffs: payoff1, payoff2, ..., payoffn
        self.payoffs_RE = re.compile(r'-?\d+\.?\d*')
        # regex for a flat event matrix: v1, v2, ..., vn
        self.events_RE = re.compile(r'(\d+)')


    def parse(self, filename):
        with open(filename) as f:
            d = f.read()        

        m = self.RE_gameparts.match(d)
        if m is None: 
            print "ERROR"

        # Game
        game = Game(m.groupdict()['name'])

        players = re.findall(self.strlist_RE, m.groupdict()['players'])

        actionlists = re.findall(self.listlist_RE, m.groupdict()['actions'])

        # Players
        for p,a in zip(players,actionlists):
            player = Player(p, re.findall(self.strlist_RE, a))
            game.players.append(player)

        # Events
        game.events.append(Event("(implicit) Zero payoff event", [0 for i in range(len(game.players))]))
        eventlists = re.findall(self.listlist_RE, m.groupdict()['events'])
        for e in eventlists:
            eventmatch = self.event_parts_RE.match(e)
            name = eventmatch.groupdict()['name']
            payoffs = [float(i) for i in re.findall(self.payoffs_RE, eventmatch.groupdict()['payoffs'])]
            game.events.append(Event(name, payoffs))

        # payoff/outcome matrix
        game.setMatrix([int(i) for i in re.findall(self.events_RE, m.groupdict()['matrix'])])

        return game

    
        



if __name__ == '__main__':
    if len(sys.argv) < 2:
        print "No .nfg file given!"
        exit

    Parser = GameParser()
    Game = Parser.parse(sys.argv[-1])
    print "\n", Game

    def iterate(players, l=[], res=[]):
        if not players:
            res.append(l)
        else:
            for i in range(len(players[0].actions)):
                iterate(players[1:], l+[i], res)

    res = []
    iterate(Game.players, [], res)
    NG = []
    for c in res:
        if Game.isNashEquilibrium(c):
            NG.append(c)

    if NG:
        print "\nNash Equilibria are:"
        for ng in NG:
            print Game.verboseActionProfile(ng)
    else:
        print "\nNo Nash Equilibria found."


